package com.why.executor;

import com.mysql.cj.jdbc.Driver;
import com.why.configurebean.MapperStatement;
import com.why.configurebean.SormProperties;
import com.why.connector.SqlSessionFactoryBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.lang.reflect.Field;
import java.lang.reflect.Type;
import java.sql.*;
import java.util.ArrayList;
import java.util.List;

public class DefaultExecutor implements Executor {
    private static final Logger logger = LoggerFactory.getLogger(SqlSessionFactoryBuilder.class);

    private SormProperties sormProperties;

    public DefaultExecutor(SormProperties sormProperties) {
        this.sormProperties = sormProperties;
    }

    @Override
    public List<Object> query(MapperStatement statement, Object param) {
        Connection connection = null;
        PreparedStatement preparedStatement = null;
        ResultSet resultSet = null;
        ArrayList<Object> result = new ArrayList<>(100);
        try {
            logger.info("开始加载驱动");
            Class.forName(sormProperties.getDriverName());
            connection = DriverManager.getConnection(sormProperties.getUrl(), sormProperties.getUserName(), sormProperties.getPassWord());
            //预编译sql
            logger.info("预编译sql");
            preparedStatement = connection.prepareStatement(statement.getSql());
            logger.info("处理占位符");
            processPlaceholder(preparedStatement, param);

            logger.info("执行sql语句");

            logger.info(statement.getSql());
            resultSet = preparedStatement.executeQuery();

            processResult(resultSet, statement, result);

        } catch (ClassNotFoundException e) {
            logger.error("加载驱动失败.{}", sormProperties.getDriverName());
            e.printStackTrace();
        } catch (SQLException e) {
            logger.error("连接sql失败.url:{},username{},password{}", sormProperties.getUrl(), sormProperties.getUserName(), sormProperties.getPassWord());
            e.printStackTrace();
        } catch (InstantiationException e) {
            logger.error("实例化对应的属性失败");
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            logger.error("访问数据失败");
            e.printStackTrace();
        }

        return result;
    }


    private void processPlaceholder(PreparedStatement statement, Object param) throws SQLException {
        if (param instanceof String) {
            statement.setString(1, (String) param);
        } else if (param instanceof Long) {
            statement.setLong(1, (Long) param);
        } else if (param instanceof Integer) {
            statement.setInt(1, (Integer) param);
        }


    }

    private void processResult(ResultSet resultSet, MapperStatement statement, List<Object> res) throws ClassNotFoundException, SQLException, InstantiationException, IllegalAccessException {

        String resultType = statement.getResultType();
        Class result = null;
        if (resultType == null || resultType.isEmpty()) {
            result = Object.class;
        } else {
            result = Class.forName(resultType);
        }


        while (resultSet.next()) {
            Object entity = result.newInstance();
            Field[] fields = entity.getClass().getDeclaredFields();
            for (Field field : fields) {
                field.setAccessible(true);
                String name = field.getName();

                Object object = resultSet.getObject(name);
                field.set(entity, object);

            }

            res.add(entity);
        }


    }


}
